package com.bfb;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AlphabetIndexer;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.SectionIndexer;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

public class ListDishes extends Activity {
	// static final String PATH_rests = "/filter/all_res";
	// static final String PATH_dish = "/filter/dishes";
	AutoCompleteTextView textView;
	ListView listdishes;
	ArrayAdapter<String> adapter, content;
	String[] list_name, list_key;
	int midpoint;
	double lat, lng;
	DishInfo[] dish;
	DefaultHttpClient CLIENT;
	Location location;
	String restaurant_key = "", restaurant_name = "", temp = "", TypeID,
			TypeName, BrowseBy, locaBY; // restaurant Key

	// Gps
	Boolean GPS = false, all = false, ByRest = false, getRest_Dishes = false,
			getType_Dishes = false, byType = false;
	private LocationManager locationManager;
	private String provider;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.list_dishes);

		Bundle inputBundle = getIntent().getExtras();
		BrowseBy = inputBundle.get("browse").toString();
		Log.e("Browse by", BrowseBy + "");
		if (BrowseBy.equals("byType")) {
			Log.e("browse", "by type");
			byType = true;
		} else if (BrowseBy.equals("Rest"))
			ByRest = true;
		else if (BrowseBy.equals("Near"))
			GPS = true;

		Log.e("Details2", "bY REST= " + ByRest + " \n GPS= " + GPS);

		CLIENT = new DefaultHttpClient();
		listdishes = (ListView) findViewById(R.id.listdishes);
		listdishes.setEmptyView(findViewById(R.id.empty));
		// listdishes.setFastScrollEnabled(true);
		textView = (AutoCompleteTextView) findViewById(R.id.autocomplete_rest);
		if (ByRest)
			textView.setHint(R.string.hint_restaurant);
		else if (byType)
			textView.setHint(R.string.hint_dishtype);
		else
			textView.setHint(R.string.hint_dish);
		textView.setThreshold(0);

		textView.setOnEditorActionListener(new OnEditorActionListener() {

			@Override
			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				if (textView.getText().toString() != "")
					if (event != null
							&& (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
						Log.e("listDishes", "Clicked Enter");
						InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
						in.hideSoftInputFromWindow(
								textView.getApplicationWindowToken(),
								InputMethodManager.HIDE_NOT_ALWAYS);
						// Log.e("rest_key", index);
						int pos = -1;
						temp = textView.getText().toString();
						int length = list_name.length;
						for (int i = 0; i < length; i++) {
							String name = list_name[i];
							if (name.equalsIgnoreCase(temp)) {
								if (all)
									pos = i;
								else if (ByRest) {
									Log.e("listDishes", "by rest");
									restaurant_name = name;
									getDishes(list_key[i]);
								} else if (byType) {
									TypeName = name;
									getDishes(list_key[i]);
								} else
									DetailView(list_key[i]);
							}
						}
						Log.e("listDishes", pos + "");

						if (pos != -1 && all) {
							Log.e("rest_key in itemclick", restaurant_key
									+ temp);

							if (pos < midpoint)
								getDishes(list_key[pos]);
							else
								DetailView(list_key[pos]);

						}

					}
				return false;
			}
		});

		textView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				Log.e("listDishes", "Clicked On list");
				temp = (String) parent.getItemAtPosition(position);
				int pos = -1;
				Log.e("listDisehs", ByRest + "Byrest, getRest" + getRest_Dishes);
				for (int i = 0; i < list_name.length; i++) {
					Log.e("listDishes", "inloop");
					if (list_name[i].equalsIgnoreCase(temp))
						if (all)
							pos = i;
						else if (ByRest) {

							Log.e("listDishes", "by rest");
							restaurant_name = list_name[i];
							getDishes(list_key[i]);
						} else if (byType) {
							TypeName = list_name[i];
							getDishes(list_key[i]);
						} else
							DetailView(list_key[i]);
				}
				if (pos != -1 && all) {
					Log.e("rest_key in itemclick", restaurant_key + temp);
					if (pos < midpoint)
						getDishes(list_key[pos]);
					else
						DetailView(list_key[pos]);
				}

			}

		});
		if (GPS)
			getByGPS();
		else
			new AutoComplete().execute();

	}

	/**
	 * This is called if the user
	 */
	public void getByGPS() {
		Log.e("GPS", "IN gps");
		startActivityForResult(new Intent(this, location.class), 0);

	}

	/**
	 * Receive the location from the location intent called if get near dishes
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		Log.e("After Get Location", resultCode + " " + requestCode);
		if (resultCode == -1 && requestCode == 0) {
			Bundle inputBundle = data.getExtras();
			lng = inputBundle.getDouble("lng");
			lat = inputBundle.getDouble("lat");
			locaBY = inputBundle.getString("LocationBy");
			Log.e("Bundle Data", lng + " " + lat + " " + locaBY);
			new AutoComplete().execute();
		}
	}

	public void getDishes(String ID) {
		if (ByRest) {
			restaurant_key = ID;
			getRest_Dishes = true;
			ByRest = false;
		} else if (byType) {
			TypeID = ID;
			getType_Dishes = true;
			byType = false;
		}
		new AutoComplete().execute();
	}

	@SuppressWarnings("unchecked")
	public void fill_list() {

		content = new MyArrayAdapter(this, R.layout.custom_list, dish);
		listdishes.setAdapter(content);

		if (dish.length != 0) {
			listdishes.setOnItemClickListener(new OnItemClickListener() {
				@Override
				public void onItemClick(AdapterView<?> parent, View view,
						int position, long id) {
					DishInfo temp = (DishInfo) parent
							.getItemAtPosition(position);
					DetailView(temp.key);

				}
			});
		} else {
			TextView tv = (TextView) findViewById(R.id.no_dishes_textview);
			tv.setText(R.string.no_dishes_found);
		}

	}

	/**
	 * Overridden onCreateOptionsMenu method. This is where the {@link Menu} for
	 * the {@link Activity} is inflated. The menu items are defined in the xml
	 * file find_dishes_menu.xml in the res/menu folder.
	 * 
	 * @param menu
	 * 
	 * @return boolean
	 * 
	 * @author Rawan Khalil(rawan.tkhalil@gmail.com)
	 * 
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.find_dishes_menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	/**
	 * Overridden onOptionsItemSelected method. This is the listener for menu
	 * item selection. It takes an input the selected item. We have 1
	 * {@link MenuItem} in the this {@link Activity}. This menu item is to
	 * create a new dish which will fire the {@link CreateDishActivity}.
	 * 
	 * @param item
	 * 
	 * @return boolean
	 * 
	 * @author Rawan Khalil(rawan.tkhalil@gmail.com)
	 * 
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.new_dish_menuitem) {
			startActivity(new Intent(getBaseContext(), CreateDishActivity.class));
			finish();
		}
		return super.onOptionsItemSelected(item);
	}

	public void MapView(View v1) {
		// loca_key is the attribute containing the restaurant key
		Intent intent = new Intent(ListDishes.this, MapViewActivity.class);
		intent.putExtra("loca_key", restaurant_key);
		System.out.print("restaurant name"+restaurant_name);
		intent.putExtra("loca_name", restaurant_name);
		startActivity(intent);

	}

	public void DetailView(String x) {
		Intent i = new Intent(this, Details.class);
		Log.e("DetailView", "putextra");
		i.putExtra("Key", x);
		Log.e("DetailView", "start");
		startActivity(i);
	}

	class AutoComplete extends AsyncTask<Void, Void, String> {

		private ProgressDialog pdia;

		@Override
		protected void onPreExecute() {
			if (ByRest)
				pdia = ProgressDialog.show(ListDishes.this, "",
						"Please wait... \n Getting All Restaurants", true);
			else if (GPS)
				pdia = ProgressDialog.show(ListDishes.this, "",
						"Please wait... \n Getting NearBy Dishes", true);
			else if (getRest_Dishes)
				pdia = ProgressDialog.show(ListDishes.this, "",
						"Please wait... \n Getting " + restaurant_name
								+ " Dishes", true);
			else if (byType)
				pdia = ProgressDialog.show(ListDishes.this, "",
						"Please wait... \n Getting All Dish Types", true);
			else if (getType_Dishes)
				pdia = ProgressDialog.show(ListDishes.this, "",
						"Please wait... \n Getting Dish of " + TypeName
								+ " type", true);
		}

		@Override
		public void onCancelled() {
			pdia.dismiss();
		}

		@Override
		protected void onPostExecute(String result) {
			Log.e("Autocomplete", "Post");
			Log.i("In Thread", "end loading");
			try {
				Log.e("jsonArray", "extract Json");
				Log.e("jsonArray", result.toString());
				if (all) {
					/**
					 * This will fill the adapter with all the restaurants and
					 * dishes the array that the adapter will take has it's
					 * first part the restaurants names and the second half is
					 * the dishes The separation is to know whether the user is
					 * choosing a restaurant or a dish
					 */
					JSONArray jsonArray = new JSONArray(result.toString());
					JSONArray rest_Object = jsonArray.getJSONObject(0)
							.getJSONArray("restaurants");
					JSONArray dish_Object = jsonArray.getJSONObject(0)
							.getJSONArray("dishes");
					int sum = rest_Object.length() + dish_Object.length(), j = 0;
					midpoint = rest_Object.length();
					list_name = new String[sum];
					list_key = new String[sum];
					for (int i = 0; i < sum; i++) {
						if (i < rest_Object.length()) {
							JSONObject jsonObject = rest_Object
									.getJSONObject(i);
							list_key[i] = jsonObject.getString("key");
							list_name[i] = jsonObject.getString("name");
						} else {
							JSONObject jsonObject = dish_Object
									.getJSONObject(j);
							list_key[i] = jsonObject.getString("key");
							list_name[i] = jsonObject.getString("name");
							j++;
						}
					}

					adapter = new ArrayAdapter<String>(ListDishes.this,
							R.layout.list_item, list_name);
					textView.setAdapter(adapter);
				} else if (ByRest || byType) {
					JSONArray jsonArray = new JSONArray(result);
					list_name = new String[jsonArray.length()];
					list_key = new String[jsonArray.length()];
					for (int i = 0; i < jsonArray.length(); i++) {
						JSONObject jsonObject = jsonArray.getJSONObject(i);
						list_key[i] = jsonObject.getString("key");
						list_name[i] = jsonObject.getString("name");
					}
					adapter = new ArrayAdapter<String>(ListDishes.this,
							R.layout.list_item, list_name);
					textView.setAdapter(adapter);
				} else {
					/**
					 * This will fill the adapter with the dishes of a specific
					 * type
					 */

					JSONArray jsonArray = new JSONArray(result);
					if (!getRest_Dishes && !getType_Dishes) {
						list_name = new String[jsonArray.length()];
						list_key = new String[jsonArray.length()];
					}
					dish = new DishInfo[jsonArray.length()];
					Log.e("list length", dish.length + "");
					for (int i = 0; i < jsonArray.length(); i++) {
						JSONObject jsonObject = jsonArray.getJSONObject(i);
						dish[i] = new DishInfo(jsonObject.getString("name"),
								jsonObject.getString("key"),
								jsonObject.getString("rate"));
						if (!getRest_Dishes && !getType_Dishes) {
							list_key[i] = jsonObject.getString("key");
							list_name[i] = jsonObject.getString("name");
						}
					}
					if (GPS) {
						adapter = new ArrayAdapter<String>(ListDishes.this,
								R.layout.list_item, list_name);
						textView.setAdapter(adapter);
					}
					if (getType_Dishes) {
						getType_Dishes = false;
						byType = true;
					}
					if (getRest_Dishes) {
						getRest_Dishes = false;
						ByRest = true;
					}
					fill_list();

				}
			} catch (Exception e) {
				Log.e("jsonArray", e.getMessage(), e);
			}
			pdia.dismiss();
		}

		@Override
		protected String doInBackground(Void... params) {
			Log.e("Autocomplete", "Back");
			StringBuilder respStr = new StringBuilder();
			URI uri;
			boolean all = false;
			try {
				HttpGet httpget;
				if (all) {
					httpget = new HttpGet("http://" + Main.SERVER
							+ "/filter/all");
				} else if (ByRest) {
					Log.e("Details", "Restaurants");
					httpget = new HttpGet("http://" + Main.SERVER
							+ "/filter/all_res");
				} else if (byType) {
					httpget = new HttpGet("http://" + Main.SERVER
							+ "/dish_types/all");
				} else {

					List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
							1);
					if (getRest_Dishes) {
						Log.e("Details", "Restaurants Dishes");
						nameValuePairs.add(new BasicNameValuePair("id",
								restaurant_key));

						uri = URIUtils
								.createURI("http", Main.SERVER, -1,
										"/filter/dishes",
										URLEncodedUtils.format(nameValuePairs,
												"UTF-8"), null);
					} else if (GPS) {
						Log.e("Details", "IN GPS");
						nameValuePairs = new ArrayList<NameValuePair>(3);
						nameValuePairs.add(new BasicNameValuePair("lat", lat
								+ ""));
						nameValuePairs.add(new BasicNameValuePair("lng", lng
								+ ""));
						nameValuePairs
								.add(new BasicNameValuePair("by", locaBY));
						uri = URIUtils
								.createURI("http", Main.SERVER, -1,
										"/func/near", URLEncodedUtils.format(
												nameValuePairs, "UTF-8"), null);
					} else {
						Log.e("Details", "TYPES");
						nameValuePairs.add(new BasicNameValuePair("id", TypeID
								+ ""));
						uri = URIUtils
								.createURI("http", Main.SERVER, -1,
										"/filter/dish_type",
										URLEncodedUtils.format(nameValuePairs,
												"UTF-8"), null);
					}
					httpget = new HttpGet(uri);

				}
				// post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
				HttpResponse resp = CLIENT.execute(httpget);
				Log.e("Details2", httpget.getURI().toString());
				StatusLine statusLine = resp.getStatusLine();
				int statusCode = statusLine.getStatusCode();
				Log.e("Details2", statusCode + "");
				if (statusCode == 200) {
					// Log.e("Details2", respStr);
					HttpEntity entity = resp.getEntity();
					InputStream content = entity.getContent();
					BufferedReader reader = new BufferedReader(
							new InputStreamReader(content));
					String line;
					while ((line = reader.readLine()) != null) {
						respStr.append(line);
					}

				} else
					Log.e("Load JSON", "Failed to download file");

			} catch (Exception e) {
				Log.e("Details", e.getMessage(), e);
			}

			return respStr.toString();
		}

	}

	@SuppressWarnings("rawtypes")
	class MyArrayAdapter extends ArrayAdapter implements SectionIndexer {
		/**
		 * Custom Dishes Adapter
		 */

		Object[] myData;
		AlphabetIndexer alphaIndexer;

		@SuppressWarnings("unchecked")
		MyArrayAdapter(Context context, int textViewResourceId, Object[] n) {
			super(context, textViewResourceId, n);
			// alphaIndexer = new AlphabetIndexer(c,c.getColumnIndex(),
			// " ABCDEFGHIJKLMNOPQRSTUVWXYZ");
			context = getContext();
			myData = n;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View v = convertView;

			if (v == null) {
				LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				v = inflater.inflate(R.layout.custom_list, null);

			}

			DishInfo y = (DishInfo) myData[position];

			TextView name = (TextView) v.findViewById(R.id.text);
			RatingBar r = (RatingBar) v.findViewById(R.id.ratebar);

			name.setText(y.name);
			r.setRating(new Float(y.rate));

			return v;
		}

		@Override
		public int getPositionForSection(int arg0) {
			// TODO Auto-generated method stub
			return alphaIndexer.getPositionForSection(arg0); // use the indexer
		}

		@Override
		public int getSectionForPosition(int position) {
			// TODO Auto-generated method stub
			return alphaIndexer.getSectionForPosition(position); // use the
																	// indexer
		}

		@Override
		public Object[] getSections() {
			// TODO Auto-generated method stub
			return alphaIndexer.getSections(); // use the indexer
		}
	}

}

class DishInfo {
	String name;
	String key;
	String rate;

	public DishInfo(String n, String k, String r) {
		name = n;
		key = k;
		rate = r;
	}

	public static void main(String[] args) {

	}
}
